class Socket {
  constructor(url, key = '') {
    this.url = url + key;
    this.socket = '';
    this.init();
    this.lockReconnect = false; //避免重复连接
    //心跳检测
    this.heartCheck = {
      timeout: 30000, //30秒
      timeoutObj: null,
      serverTimeoutObj: null,
      reset: () => {
        clearTimeout(this.heartCheck.timeoutObj);
        clearTimeout(this.heartCheck.serverTimeoutObj);
        return this.heartCheck;
      },
      start: () => {
        this.heartCheck.timeoutObj = setTimeout(() => {
          //这里发送一个心跳，后端收到后，返回一个心跳消息，
          //onmessage拿到返回的心跳就说明连接正常
          let obj = 'heart_care';
          this.send(obj);
          this.heartCheck.serverTimeoutObj = setTimeout(() => {
            //如果超过一定时间还没重置，说明后端主动断开了
            this.socket.close(); //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
          }, this.heartCheck.timeout);
        }, this.heartCheck.timeout);
      },
    };
  }
  init() {
    //判断当前浏览器支持不支持WebSocket
    if ('WebSocket' in window) {
      this.socket = new WebSocket(this.url);
    } else {
      console.warn('该浏览器不支持WebSocket，请切换浏览器或升级后再试');
      return;
    }
    this.onopen();
    this.onclose();
  }
  onopen = () => {
    this.socket.onopen = () => {
      console.warn('链接成功！');
      this.heartCheck.reset().start(); //传递信息
    };
  };
  onclose = () => {
    this.socket.onclose = () => {
      console.warn('链接断开！');
      this.reconnect();
    };
  };
  onmessage = (callback) => {
    this.socket.onmessage = (option) => {
      //针对那些指令进行跳过
      let errArr = [
        '连接成功',
        'heart_care',
        '链接成功！',
        '链接断开！',
        'heat_core',
        'head_core',
      ];
      let data = option.data;
      if (errArr.indexOf(data) >= 0) {
        this.heartCheck.reset().start();
        return;
      }
      let obj = JSON.stringify('heart_care');
      if (data !== obj) {
        data = JSON.parse(data);
        callback(data);
      }
    };
  };
  reconnect = () => {
    if (this.lockReconnect) return;
    this.lockReconnect = true;
    //没连接上会一直重连，设置延迟避免请求过多
    setTimeout(() => {
      this.init();
      this.lockReconnect = false;
    }, 5000);
  };
  send = (option) => {
    this.socket.send(option);
  };
  close = () => {
    this.socket.close();
  };
}
export default Socket;
